#ifndef FILEMODEL_H
#define FILEMODEL_H

////////////////////////////////////////////////////////////////////
// TFileItem ///////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//
class TFileItem
{
public:
	TFileItem( const QFileInfo &fInfo, bool virtFolder = false, TFileItem *parent = NULL );
	TFileItem( QString filePath, bool virtFolder = false, TFileItem *parent = NULL );
	~TFileItem();
	//
	QString   filePath()		const	{ return info.filePath(); }
	QString   fileName()		const;
	QString   fileExt()			const	{ return info.suffix(); }
	qint64    fileSizeInBytes()	const	{ return info.size(); }
	QString	  fileSize()		const;
	QDateTime fileDateTime()	const	{ return info.lastModified(); }
	const QFileInfo &fileInfo() const	{ return info; }
	//
	bool isDir()				const	{ return info.isDir() && !info.isSymLink() || virtualFolder; }
	bool isVirtual()			const	{ return virtualFolder; }
	bool isSymLink()			const   { return info.isSymLink(); }
	QString symLinkTarget()		const   { return info.symLinkTarget(); }
	//
	void addChild( TFileItem *item );
	void insertChild( TFileItem *item, int pos );
	//
	void fetchChildren();
	bool getFetched()		const	{ return fetched; }
	//
	TFileItem *child(int i)	const	{ return children.at(i); }
	int childCount()		const	{ return children.count(); }
	TFileItem *parent()		const	{ return itemParent; }
	//
	bool synchronizeWithDir( const QFileInfoList &fileList);
	//
private:
	TFileItem *itemParent;
	QList<TFileItem*> children;
	//
	QIcon     icon;
	QFileInfo info;
	bool fetched
	   , virtualFolder;
	//
	friend class TFileModel;
};


////////////////////////////////////////////////////////////////////
// TFileModel //////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//
class TFileModel : public QAbstractItemModel
{
	Q_OBJECT
public:
	enum Columns
	{
		NameColumn = 0,
		SizeColumn,
		TypeColumn,
		DateColumn
	};
	//
	TFileModel();
	~TFileModel() { delete rootItem; }
	//
	virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
	virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
	virtual QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
	virtual QModelIndex parent(const QModelIndex &index) const;
	virtual bool hasChildren(const QModelIndex &index = QModelIndex()) const;
	//
	virtual void fetchMore(const QModelIndex &index);
	virtual bool canFetchMore(const QModelIndex &index) const;
	//
	virtual Qt::ItemFlags flags(const QModelIndex &index) const { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; }
	virtual int rowCount(const QModelIndex &parent = QModelIndex()) const { return getItem(parent)->childCount(); }
	virtual int columnCount(const QModelIndex &parent = QModelIndex()) const { return ColumnCount; }
	//
	TFileItem *getItem( const QModelIndex index ) const;
	TFileItem *getRootItem()  const { return rootItem; }
	QModelIndex myComputer()  const { return indexMyComputer; }
	QModelIndex myDocuments() const { return indexMyDocuments; }
	QModelIndex myDesktop()   const { return indexDesktop; }
	//
//	void setFSWatching( bool needFSWatch ) { fsWatching = needFSWatch; }

private slots:
	void slotDrivesTimeout();

signals:
	void pathUpdated( QString path );
	void pathAboutToBeUpdated( QString path );

private:
	TFileItem *rootItem;
	//
	static const int ColumnCount = 4;
	//
	QFileIconProvider iconProvider;
	mutable QHash<QString, QIcon>   extToIcon;
	mutable QHash<QString, QString> extToType;
	//
	TFileItem *createWinSysFolder( int folder );
	//
	QModelIndex indexDesktop
			  , indexMyDocuments
			  , indexMyComputer;
	TFileItem   *itemDesktop
		      , *itemMyDocuments
			  , *itemMyComputer;
	//
//	bool fsWatching;
//	QFileSystemWatcher fsWatcher;
	QTimer drivesTimer;
	void initDrivesTimer();

};


////////////////////////////////////////////////////////////////////
// TFileProxyModel /////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//
class TFileProxyModel : public QSortFilterProxyModel
{
	Q_OBJECT
public:
	TFileProxyModel( QObject *parent = 0 ): QSortFilterProxyModel(parent) {}
	virtual void fetchMore(const QModelIndex &index);
	virtual bool hasChildren(const QModelIndex &index = QModelIndex()) const;
	virtual bool canFetchMore(const QModelIndex &index) const;
	virtual void setSourceModel( TFileModel *sourceModel );
	//
	void setFilteringEnable( bool filtering ){ filter = filtering; }
	//
	TFileItem *getItemFromSource(QModelIndex index) const;
	TFileItem *getItemFromProxy(QModelIndex index) const;

signals:
	void pathAboutToBeUpdated( QString path );
	void pathUpdated( QString path );

protected:
	virtual bool filterAcceptsRow ( int source_row, const QModelIndex & source_parent ) const;
	virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const;
	//
	bool filter;
	TFileModel *fileModel;
};

////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
//
QModelIndex expandToPathInTreeView( QTreeView *view
								  , const QString &path
								  , const QString &myDocumentsPath
								  , QModelIndex myDocumentsIndex
								  , const QString &myDesktopPath
								  , QModelIndex myDesktopIndex
								  , QModelIndex myComputerIndex );

////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////

#endif
